package top.lyjwn.todo.aop.interceptor;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import top.lyjwn.todo.aop.log.http.HttpLogE;
import top.lyjwn.todo.aop.log.http.HttpLogHandle;
import top.lyjwn.todo.aop.log.http.request.ServletRequestWrapper;
import top.lyjwn.todo.aop.log.http.response.ServletResponseWrapper;
import top.lyjwn.todo.common.utils.UniqueUtil;

import java.text.MessageFormat;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.Optional;

public class LogInterceptor implements HandlerInterceptor {


    private HttpLogHandle httpLogHandle;

    public LogInterceptor(HttpLogHandle httpLogHandle) {
        this.httpLogHandle = httpLogHandle;
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (Optional.ofNullable(httpLogHandle).isPresent() && request instanceof ServletRequestWrapper request1) {
            HttpLogE log = new HttpLogE();
            log.setUrl(request.getRequestURI());
            String token = request.getHeader("token");
            log.setToken(token);
            log.setIp(request.getRemoteAddr());
            log.setMethod(request.getMethod());
            log.setRequestContentType(request.getHeader("Accept"));
            log.setRequestContent(request1.getContentAsString());
            log.setBeginTime(LocalDateTime.now());
            httpLogHandle.in(MessageFormat.format("""
                    [Flag Id]         : {0}
                    [Request Time]    : {1}
                    [HTTP Method]     : {2}
                    [Request URL]     : {3}
                    [Token]           : {4}
                    [Client IP]       : {5}
                    [Request Params]  : unparsed
                    """, request1.getFlagId(), log.getBeginTime(), log.getMethod(), log.getUrl(), log.getToken(), log.getIp()));
        }
        String uuid = UniqueUtil.getUUID();
        return HandlerInterceptor.super.preHandle(new ServletRequestWrapper(uuid, request), new ServletResponseWrapper(uuid, response), handler);
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
        if (Optional.ofNullable(httpLogHandle).isPresent()) {
            HttpLogE log = new HttpLogE();
            if (request instanceof ServletRequestWrapper request1) {
                log.setRequest(request1);
                httpLogHandle.in(MessageFormat.format("""
                        [Flag Id]         : {0}
                        [Request Time]    : {1}
                        [HTTP Method]     : {2}
                        [Request URL]     : {3}
                        [Token]           : {4}
                        [Client IP]       : {5}
                        [Request Params]  : {6}
                        """, request1.getFlagId(), log.getBeginTime(), log.getMethod(), log.getUrl(), log.getToken(), log.getIp(), log.getRequestContent()));
            }
            if (response instanceof ServletResponseWrapper response1) {
                log.setResponse(response1);
                httpLogHandle.out(MessageFormat.format("""
                        [Flag Id]         : {0}
                        [Response Status] : {1}
                        [Response Time]   : {2}
                        [Response Use Time]   : {3}ms
                        [Response Data]   : {4}
                        """, response1.getFlagId(), log.getResponseStatus(), log.getEndTime(), Duration.between(log.getBeginTime(), log.getEndTime()).toMinutes(), log.getResponseContent()));
            }
        }
    }
}
